﻿using AntdUI;
using AntdUI.Icon;
using CodeGenerator.DBInfo.metadata;
using CodeGenerator.Utils;
using Google.Protobuf.WellKnownTypes;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.StartPanel;

namespace CodeGenerator.Dialog
{
    public partial class TemplateConfigDialog : Form
    {
        private Column[] TplTableHeaders = { new Column("TplName", "模板名称", ColumnAlign.Center), new Column("TplPath", "模板路径", ColumnAlign.Center) };
        AntList<dynamic> TplList = new AntList<dynamic>();
        ConfigUtil Config { get; } = new ConfigUtil(ConfigUtil.TemplateFile);
        JToken AppConfig = null;
        JObject SelectedTemplate = null;
        List<RemoteTemplate> remoteList = new List<RemoteTemplate>();
        public TemplateConfigDialog()
        {
            //禁用大小可调整性
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
            //禁用最大化按钮
            this.MaximizeBox = false;
            InitializeComponent();
            try
            {
                LoadRemoteTemplates();
            }
            catch (Exception ex)
            {
                loadingUpdateInfoBtn.Visible = false;
                throw ex;
            }
        }
        /// <summary>
        /// 加载共享模板列表
        /// </summary>
        public void LoadRemoteTemplates()
        {
            var config = new ConfigUtil(ConfigUtil.AppConfigFile);
            var configs = config.GetConfigs();
            if (configs.Count == 0) return;
            AppConfig = configs[0];

            var rootUrl = AppConfig["appUpdateUrl"].ToString();
            rootUrl = $"{rootUrl}{(rootUrl.EndsWith("/") ? "" : "/")}";
            var remoteTemplatesUrl = $"{rootUrl}templates.json";
            Task.Run(async () =>
            {
                //获取远端模板列表
                try
                {
                    remoteList = await UpdateUtil.GetRemoteTemplates(remoteTemplatesUrl);
                }
                catch (Exception ex)
                {
                    throw ex;
                }
                finally
                {
                    Invoke(new Action(() => loadingUpdateInfoBtn.Visible = false));
                }
            });
        }
        public string TemplateType
        {
            get
            {
                var type = "front";
                if (typeSegmented.SelectIndex == 1)
                {
                    type = "back";
                }
                return type;
            }
        }
        public string TemplateTypeName
        {
            get
            {
                var name = "前端";
                if (typeSegmented.SelectIndex == 1)
                {
                    name = "后端";
                }
                return name;
            }
        }
        public bool TemplateTypeIsFront
        {
            get
            {
                return TemplateType == "front";
            }
        }
        /// <summary>
        /// 初始化模板列表
        /// </summary>
        private void InitTplTable()
        {
            tplTable.Columns = TplTableHeaders;
            TplTableHeaders[0].Width = "80";
            TplList.Clear();
            foreach (var template in Config.GetConfigs())
            {
                if (template["Type"].ToString() == TemplateType)
                {
                    TplList.Add(template);
                }
            }
            tplTable.Binding(TplList);
        }

        private void TemplateConfigDialog_Load(object sender, EventArgs e)
        {
            InitTplTable();
        }

        private void typeSegmented_SelectIndexChanged(object sender, int value)
        {
            InitTplTable();
        }

        private void addTpl_Click(object sender, EventArgs e)
        {
            SelectedTemplate = null;
            versionBadge.Text = "1";
            tplName.Text = "";
            tplPath.Text = "";
            tplTypeName.Text = TemplateTypeName + "模板";
            tplTypeName.Type = TemplateTypeIsFront ? TTypeMini.Primary : TTypeMini.Success;
            localTemplateSymbol.Text = "本地";
            localTemplateSymbol.Type = TTypeMini.Default;
            updateBtn.Visible = false;
        }
        private TemplateInfo GetTemplateInfo()
        {
            return new TemplateInfo() { RemoteId = null, TplName = tplName.Text, TplPath = tplPath.Text, Version = int.Parse(versionBadge.Text) };
        }
        private void saveTpl_Click(object sender, EventArgs e)
        {
            var tplInfo = GetTemplateInfo();
            if (tplInfo.TplPath.IsNullOrEmpty())
            {
                throw new Exception("模板路径不能为空");
            }
            if (tplInfo.TplName.IsNullOrEmpty())
            {
                throw new Exception("模板名称不能为空");
            }
            var exists = Directory.Exists(tplInfo.TplPath);
            if (!exists)
            {
                throw new Exception("模板路径不存在");
            }
            if (SelectedTemplate != null)
            {
                //直接保存
                tplInfo.Version = tplInfo.Version++;
                var remoteId = SelectedTemplate["RemoteId"];
                tplInfo.Type = SelectedTemplate["Type"].ToString();
                if (remoteId != null)
                {
                    tplInfo.RemoteId = remoteId.ToString();
                }
                var json = Config.ToJsonObj(tplInfo);
                json.Add("id", SelectedTemplate["id"]);
                Config.UpdateConfig(json);
            }
            else
            {
                //新配置
                tplInfo.Type = TemplateType;
                int id = Config.AddConfig(tplInfo);
                var json = Config.ToJsonObj(tplInfo);
                json.Add("id", id);
                SelectedTemplate = json;
            }
            InitTplTable();
        }

        private void tplTable_DoubleClick(object sender, EventArgs e)
        {
            var tb = sender as Table;
            dynamic tplInfo = TplList[tb.SelectedIndex - 1];
            int localVersion = int.Parse(tplInfo["Version"].ToString());
            string localRemoteId = tplInfo["RemoteId"].ToString();
            SelectedTemplate = tplInfo;
            tplName.Text = tplInfo["TplName"];
            tplPath.Text = tplInfo["TplPath"];
            versionBadge.Text = localVersion.ToString();
            tplTypeName.Text = tplInfo["Type"] == "front" ? "前端模板" : "后端模板";
            localTemplateSymbol.Text = localRemoteId.IsNullOrEmpty() ? "本地" : "共享";
            localTemplateSymbol.Type = localRemoteId.IsNullOrEmpty() ? TTypeMini.Default : TTypeMini.Primary;
            delTpl.Enabled = true;
            //判断是否需要更新版本
            var remoteId = localRemoteId.ToString();
            var res = remoteList.Where(x => x.Id == localRemoteId && x.Version > localVersion).ToList();
            updateBtn.Visible = res.Count > 0;
        }

        private void pathSelectBtn_Click(object sender, EventArgs e)
        {
            var fsd = new FolderSelectDialog();
            fsd.Title = "请选择模板文件路径";
            var show = fsd.ShowDialog();
            if (!show) return;
            var path = fsd.FileName;
            var tplJsonPath = path + "\\template.json";
            if (!File.Exists(tplJsonPath))
            {
                throw new Exception("无效的路径，路径必须包含template.json文件");
            }
            var text = File.ReadAllText(tplJsonPath);
            try
            {
                var json = JsonConvert.DeserializeObject<JObject>(text);
                tplName.Text = json["name"].ToString() ?? "";
                tplPath.Text = path;
            }
            catch (Exception ex)
            {
                throw new Exception($"template.json文件解析错误\n{ex.Message}");
            }
        }

        private void openTplPath_Click(object sender, EventArgs e)
        {
            var path = CommonUtil.GenFullPath(tplPath.Text);
            if (path.IsNullOrEmpty())
            {
                throw new Exception("模板路径为空");
            }
            if (!Directory.Exists(path))
            {
                throw new Exception("模板路径不存在");
            }
            Process.Start(path);
        }

        private void delTpl_Click(object sender, EventArgs e)
        {
            var result = AntdUI.Modal.open(new AntdUI.Modal.Config(this, "提示", "是否删除该模板？", TType.Warn)
            {
                CancelText = "取消",
                OkText = "确定"
            });
            if (result == DialogResult.OK)
            {
                Config.RemoveConfig(SelectedTemplate);
                addTpl_Click(null, null);
                InitTplTable();
            }
        }

        private void helpBtn_Click(object sender, EventArgs e)
        {
            HelpDialog dialog = new HelpDialog();
            dialog.StartPosition = FormStartPosition.CenterParent;
            dialog.ShowDialog();
        }
        public class RemoteTemplate
        {
            public string Id { get; set; }
            public string Name { get; set; }
            public int Version { get; set; }
            public string RelativePath { get; set; }
            public string Type { get; set; }
        }

        private void updateBtn_Click(object sender, EventArgs e)
        {
            updateBtn.Text = "";
            updateBtn.Loading = true;

            var dlgRes = AntdUI.Modal.open(new AntdUI.Modal.Config(this, "提示", "是否更新此模板？", AntdUI.TType.Info)
            {
                CancelText = "取消",
                OkText = "确定"
            });
            try
            {
                if (dlgRes != DialogResult.OK)
                {
                    return;
                }
                dynamic tplInfo = TplList[tplTable.SelectedIndex - 1];
                var localRemoteId = tplInfo["RemoteId"].ToString();
                var localTplDir = tplInfo["TplPath"].ToString();
                var remoteTpl = remoteList.Where(x => x.Id == localRemoteId).ToList()[0];
                var rootUrl = AppConfig["appUpdateUrl"].ToString();
                rootUrl = $"{rootUrl}{(rootUrl.EndsWith("/") ? "" : "/")}";
                //下载新模板
                var downUrl = $"{rootUrl}{remoteTpl.RelativePath}";
                var downPath = CommonUtil.GenFullPath($"tmp/{remoteTpl.Id}.zip");
                UpdateUtil.DownloadFile(downUrl, downPath);
                //解压到临时目录
                var extractTmpPath = CommonUtil.GenFullPath($"tmp/{remoteTpl.Name}");
                if (Directory.Exists(extractTmpPath))
                {
                    FileUtil.DeleteDirectory(extractTmpPath);
                }
                ZipFile.ExtractToDirectory(downPath, extractTmpPath);
                //清空旧的模板路径
                FileUtil.DeleteDirectory(localTplDir);
                //复制到新路径
                FileUtil.CopyDirectoryFiles(extractTmpPath, localTplDir);
                //保存新信息
                versionBadge.Text = remoteTpl.Version.ToString();
                saveTpl_Click(null, null);
                updateBtn.Visible = false;
                AntdUI.Modal.open(new AntdUI.Modal.Config(this, "提示", "更新完成", AntdUI.TType.Success)
                {
                    CancelText = null,
                    OkText = "确定"
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                updateBtn.Text = "更新";
                updateBtn.Loading = false;
            }
        }
    }
}
